<template>
  <div class="image-upload">
    <!-- 图片预览区域 -->
    <div v-if="imageUrl" class="image-preview">
      <img :src="previewUrl" :alt="alt" class="preview-image" />
      <div class="image-overlay">
        <div class="image-actions">
          <el-button
            type="primary"
            size="small"
            :icon="View"
            circle
            @click="handlePreview"
            title="预览"
          />
          <el-button
            type="danger"
            size="small"
            :icon="Delete"
            circle
            @click="handleRemove"
            title="删除"
          />
        </div>
      </div>
    </div>

    <!-- 上传区域 -->
    <div v-else class="upload-area" @click="triggerUpload">
      <el-icon class="upload-icon"><Plus /></el-icon>
      <div class="upload-text">{{ placeholder }}</div>
      <div class="upload-hint">{{ hint }}</div>
      <div class="upload-actions" @click.stop>
        <el-button type="primary" size="small" @click="triggerUpload">
          上传图片
        </el-button>
      </div>
    </div>

    <!-- 隐藏的文件输入 -->
    <input
      ref="fileInputRef"
      type="file"
      accept="image/*"
      style="display: none"
      @change="handleFileChange"
    />

    <!-- 图片预览对话框 -->
    <el-dialog
      v-model="showPreviewDialog"
      title="图片预览"
      width="60%"
      :before-close="closePreviewDialog"
    >
      <div class="preview-dialog-content">
        <img :src="previewUrl" :alt="alt" class="dialog-preview-image" />
      </div>
    </el-dialog>

    <!-- 加载状态 -->
    <div v-if="uploading" class="upload-loading">
      <el-icon class="is-loading"><Loading /></el-icon>
      <span>上传中...</span>
    </div>

    <div class="upload-placeholder">
      
    </div>

  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onUnmounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus, View, Delete, Loading } from '@element-plus/icons-vue'
import { uploadImage, getImagePreviewUrl, createImagePreview, revokeImagePreview, getProxiedImageUrl, getFullImageUrl, validateImageUrl } from '@/utils/upload'
import type { UploadFile } from '@/types/admin'


interface Props {
  modelValue?: string
  placeholder?: string
  hint?: string
  alt?: string
  width?: string
  height?: string
  disabled?: boolean
}

interface Emits {
  (e: 'update:modelValue', value: string): void
  (e: 'upload-success', url: string): void
  (e: 'upload-error', error: string): void
  (e: 'remove'): void
}

const props = withDefaults(defineProps<Props>(), {
  placeholder: '点击上传图片',
  hint: '支持 JPG、PNG、GIF、WebP 格式，大小不超过 5MB',
  alt: '图片',
  width: '120px',
  height: '120px',
  disabled: false
})

const emit = defineEmits<Emits>()

const fileInputRef = ref<HTMLInputElement>()
const uploading = ref(false)
const showPreviewDialog = ref(false)

const localPreviewUrl = ref('')

// 计算属性
const imageUrl = computed(() => props.modelValue)

const previewUrl = computed(() => {
  if (localPreviewUrl.value) {
    return localPreviewUrl.value
  }
  if (imageUrl.value) {
    let url = imageUrl.value
    
    // 开发环境处理
    if (import.meta.env.DEV) {
      // 如果是完整URL，提取路径
      if (url.startsWith('http://') || url.startsWith('https://')) {
        try {
          const urlObj = new URL(url)
          url = urlObj.pathname
        } catch {
          // URL解析失败，使用原始URL
        }
      }
      // 确保是相对路径
      url = url.startsWith('/') ? url : '/' + url
    } else {
      // 生产环境使用完整URL
      url = getImagePreviewUrl(url)
    }
    
    console.log('图片预览URL处理:', { 
      original: imageUrl.value, 
      processed: url,
      isDev: import.meta.env.DEV 
    })
    return url
  }
  return ''
})

// 触发文件选择
const triggerUpload = () => {
  if (props.disabled || uploading.value) return
  fileInputRef.value?.click()
}

// 处理文件选择
const handleFileChange = async (event: Event) => {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]
  
  if (!file) return

  try {
    uploading.value = true
    
    // 创建本地预览
    localPreviewUrl.value = createImagePreview(file)
    
    // 上传图片
    const result = await uploadImage(file)
    console.log('图片上传成功:', result)
    
    // 清理本地预览
    if (localPreviewUrl.value) {
      revokeImagePreview(localPreviewUrl.value)
      localPreviewUrl.value = ''
    }
    
    // 验证返回的URL
    if (!validateImageUrl(result)) {
      throw new Error('服务器返回的图片URL格式无效')
    }
    
    // 更新值 - 使用完整URL
    const fullUrl = getFullImageUrl(result)
    emit('update:modelValue', fullUrl)
    emit('upload-success', fullUrl)
    
    ElMessage.success('图片上传成功')
  } catch (error: any) {
    console.error('图片上传失败:', error)
    
    // 清理本地预览
    if (localPreviewUrl.value) {
      revokeImagePreview(localPreviewUrl.value)
      localPreviewUrl.value = ''
    }
    
    const errorMessage = error.message || '图片上传失败'
    emit('upload-error', errorMessage)
    ElMessage.error(errorMessage)
  } finally {
    uploading.value = false
    // 清空文件输入
    if (target) {
      target.value = ''
    }
  }
}

// 预览图片
const handlePreview = () => {
  if (previewUrl.value) {
    showPreviewDialog.value = true
  }
}

// 删除图片
const handleRemove = async () => {
  try {
    await ElMessageBox.confirm(
      '确定要删除这张图片吗？',
      '删除确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }
    )
    
    emit('update:modelValue', '')
    emit('remove')
    ElMessage.success('图片已删除')
  } catch {
    // 用户取消
  }
}

// 关闭预览对话框
const closePreviewDialog = () => {
  showPreviewDialog.value = false
}



// 清理资源
onUnmounted(() => {
  if (localPreviewUrl.value) {
    revokeImagePreview(localPreviewUrl.value)
  }
})

// 监听外部值变化
watch(() => props.modelValue, (newValue) => {
  if (!newValue && localPreviewUrl.value) {
    revokeImagePreview(localPreviewUrl.value)
    localPreviewUrl.value = ''
  }
})
</script>

<style scoped>
.image-upload {
  position: relative;
  display: inline-block;
  width: v-bind(width);
  height: v-bind(height);
}

.upload-area {
  width: 100%;
  height: 100%;
  border: 2px dashed #d9d9d9;
  border-radius: 8px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.3s ease;
  background: #fafafa;
  position: relative;
}

.upload-area:hover {
  border-color: #409eff;
  background: #f0f9ff;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
}

.upload-area:active {
  transform: translateY(0);
}

.upload-icon {
  font-size: 28px;
  color: #c0c4cc;
  margin-bottom: 8px;
}

.upload-text {
  font-size: 14px;
  color: #606266;
  margin-bottom: 4px;
}

.upload-hint {
  font-size: 12px;
  color: #909399;
  text-align: center;
  line-height: 1.4;
  margin-bottom: 12px;
}

.upload-actions {
  display: flex;
  gap: 8px;
  justify-content: center;
}

.image-preview {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 8px;
  overflow: hidden;
  border: 1px solid #e4e7ed;
}

.preview-image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s ease;
}

.image-preview:hover .image-overlay {
  opacity: 1;
}

.image-actions {
  display: flex;
  gap: 8px;
}

.upload-loading {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  font-size: 14px;
  color: #409eff;
}

.upload-loading .el-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.preview-dialog-content {
  text-align: center;
}

.dialog-preview-image {
  max-width: 100%;
  max-height: 60vh;
  object-fit: contain;
}

/* 响应式 */
@media (max-width: 768px) {
  .upload-hint {
    font-size: 10px;
  }
  
  .upload-text {
    font-size: 12px;
  }
  
  .upload-icon {
    font-size: 24px;
  }
}
</style> 